/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package videostoreapp;

import java.io.Serializable;
import java.util.List;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.jms.ConnectionFactory;
import javax.jms.Destination;
import javax.jms.JMSException;
import javax.jms.Message;
import javax.jms.MessageConsumer;
import javax.jms.MessageListener;
import javax.jms.MessageProducer;
import javax.jms.ObjectMessage;
import javax.jms.Session;
import javax.jms.TextMessage;
import videostoreapp.Order.OrderInfo;
import videostoreapp.dataobjects.OrderDO;
import videowarehouseapp.Delivery.DeliveryInfo;
import videowarehouseapp.Stock.StockInfo;
import videowarehouseapp.StockDO;

/**
 *
 * @author oiiv2253
 */
public class OrderMgr {

    private static OrderMgr mgr;
    private ConnectionFactory getCxn;
    private Destination getDest;
    private javax.jms.Connection conn;
    private MessageConsumer consumer;
    private Session sess;
    private ConnectionFactory sendCxn;
    private Destination sendDest;

    private OrderMgr() throws Exception {

        getCxn = Constants.getOrderConnectionFactory();
        getDest = Constants.getOrderQueue();

        sendCxn = Constants.getDeliveryConnectionFactory();
        sendDest = Constants.getDeliveryQueue();

    }

    public static OrderMgr getInstance() throws Exception {

        if (mgr == null) {
            mgr = new OrderMgr();
        }
        return mgr;

    }

    public void startQueueListener() throws Exception {
        //create connection
        conn = sendCxn.createConnection();
        sess = conn.createSession(false, Session.AUTO_ACKNOWLEDGE);
        try {
            consumer = sess.createConsumer(sendDest);
            consumer.setMessageListener(new MessageListener() {

                public void onMessage(Message message) {
                    System.out.println("it works!");
                    try {
                        OrderMgr.getInstance().treatMessage(message);
                    } catch (Exception ex) {
                        Logger.getLogger(OrderMgr.class.getName()).log(Level.SEVERE, null, ex);
                    }
                }
            });
            conn.start();
        } catch (JMSException e) {
            System.err.println("Exception occurred: " + e.toString());
        }
    }

    public void stopQueueListener() throws Exception {
        conn.close();
    }

    public void treatMessage(Message message) throws JMSException, Exception {

        String messageType = message.getJMSType();

        System.out.println("Handling a message");
        System.out.println("Message type is " + messageType);

        if (messageType.equals("deliveryInfo")) {
            System.out.println("Updating delivery status");
            updateDelivery(message);
        }

        if (messageType.equals("warehouse")) {
            System.out.println("Updating delivery stock");
            updateStock(message);
        }

    }

    public void sendOrderMessage(OrderInfo oi) {
        try {
            //create connection
            javax.jms.Connection conn = getCxn.createConnection();
            Session session = conn.createSession(false, Session.AUTO_ACKNOWLEDGE);

            MessageProducer prod = session.createProducer(getDest);
            ObjectMessage msg = session.createObjectMessage();

            msg.setJMSType("order");
            msg.setObject(oi);
            prod.send(msg);

        } catch (Exception ex) {
            Logger.getLogger(OrderMgr.class.getName()).log(Level.SEVERE, null, ex);
        }
    }

    public void sendDeliveryQuery(int deliveryID) {

        try {
            //create connection
            javax.jms.Connection conn = getCxn.createConnection();
            Session session = conn.createSession(false, Session.AUTO_ACKNOWLEDGE);

            MessageProducer prod = session.createProducer(getDest);
            TextMessage msg = session.createTextMessage();

            msg.setJMSType("status");
            msg.setIntProperty("DeliveryID", deliveryID);
            prod.send(msg);

        } catch (Exception ex) {
            Logger.getLogger(OrderMgr.class.getName()).log(Level.SEVERE, null, ex);
        }

    }

    public void requestStockByWarehouse(String warehouse) {

        try {
            //create connection
            javax.jms.Connection conn = getCxn.createConnection();
            Session session = conn.createSession(false, Session.AUTO_ACKNOWLEDGE);

            MessageProducer prod = session.createProducer(getDest);
            TextMessage msg = session.createTextMessage();

            msg.setJMSType("warehouse");
            msg.setStringProperty("warehouse", warehouse);
            prod.send(msg);

        } catch (Exception ex) {
            Logger.getLogger(OrderMgr.class.getName()).log(Level.SEVERE, null, ex);
        }

    }

    private void updateDelivery(Message message) {
        try {
            ObjectMessage om = (ObjectMessage) message;
            DeliveryInfo dInfo = (DeliveryInfo) om.getObject();
            System.out.println("This is delivery message with id  " + dInfo.id);
            OrderDO ordDO = new OrderDO();
            ordDO.updateOrderStatusWithDeliveryId(dInfo.orderId, dInfo.status, dInfo.id);
            
            OrderInfo oInfo = ordDO.getOrderById(dInfo.orderId);
            if (oInfo != null) {
                System.out.println("Order" + dInfo.orderId + " status updated to " + oInfo.status);
            }else {
                System.out.println("Order not found");
            }
        } catch (JMSException ex) {
            Logger.getLogger(OrderMgr.class.getName()).log(Level.SEVERE, null, ex);
        }

    }

    private void updateStock(Message message) {

        try {
            ObjectMessage om = (ObjectMessage) message;
            List<StockInfo> stock = (List<StockInfo>) om.getObject();

            for (StockInfo sInfo : stock) {

                StockDO stockDo = new StockDO();

                StockInfo id = stockDo.getItemById(sInfo.id);

                if(id == null) {
                    stockDo.createItem(sInfo);
                }else {
                    stockDo.modifyItem(sInfo);
                }
            }

        }
        catch (JMSException ex) {
            Logger.getLogger(OrderMgr.class.getName()).log(Level.SEVERE, null, ex);
        }

    }
}
